/**
 * dbms-sjtu
 * Buffer.java created at Aug 15, 2011
 */
package dbms.buffer;

import dbms.Constants;
import dbms.disk.Page;
import dbms.disk.PageFormatter;

/**
 * @author weapon
 *
 */
public class Buffer {
	public Page page = new Page();
	public int blockNum = -1;
	public int modified = 0;
	public int readWriteTime = 0;
	
	/**
	 * Write this buffer's content to database file if it is dirty.
	 */
	public void flush(){
		if(this.modified > 0){
			page.write(blockNum);
			this.modified = 0;
			this.blockNum = -1;
			this.readWriteTime = 0;
		}
	}
	
	/**
	 * read a block from database file
	 * @param blk: the block which will connect to
	 */
	public void connectToBlock(int blk){
		this.flush();
		this.blockNum = blk;
		this.page.read(blk);
		this.modified = 0;
		this.readWriteTime = 0;
	}
	
	/**
	 * format a page by different PageFormatter, then write to database file.<br>
	 * eg. create table
	 * @param pageFormatter: masterpage, recordpage, overflowpage
	 */
	public void appendNew(PageFormatter pageFormatter){
		this.flush();
		pageFormatter.format(this.page);
		this.blockNum = this.page.append();
		this.modified = 0;
		this.readWriteTime = 0;
	}
	
	/**
	 * eraser the data in this buffer
	 */
	public void clear(){
		for(int i = 0; i < Constants.BLOCKSIZE / Constants.INT_SIZE; i++){
			this.page.setInt(i * Constants.INT_SIZE, 0);
		}
	}
	
	/**
	 * The following four method is same as object Page.
	 */
	public int getInt(int offset){
		this.readWriteTime++;
		return this.page.getInt(offset);
	}
	
	public void setInt(int offset, int value){
		this.modified++;
		this.readWriteTime++;
		this.page.setInt(offset, value);
	}
	
	public float getFloat(int offset){
		this.readWriteTime++;
		return this.page.getFloat(offset);
	}
	
	public void setFloat(int offset, float value){
		this.modified++;
		this.readWriteTime++;
		this.page.setFloat(offset, value);
	}
	
	
	
	
	
	public String getString(int offset, int length){
		this.readWriteTime++;
		return this.page.getString(offset, length);
	}
	
	public void setString(int offset, String val){
		this.modified++;
		this.readWriteTime++;
		this.page.setString(offset, val);
	}
	
	public int getBlockNum(){
		return this.blockNum;
	}
	
	public int getReadWriteTime(){
		return this.readWriteTime;
	}
	
	public boolean isModified(){
		return this.modified > 0;
	}
	
	public boolean isUsed(){
		return this.blockNum > -1;
	}
}
